xss_terminate now Rails 2.2 ready; code now on GitHub

Posted by Luke Francl
on Friday, December 19

I had some coffee a bit too late yesterday and it inspired me to a boost of productivity on xss_terminate, my plugin that escapes HTML from your models when you save them.

xss_terminate now supports Rails 2.2. It is backwards compatible with Rails 2.0 and 2.1.

I also moved the plugin source to GitHub, and incorporated a bug fix from redinger.

You can install it using

script/plugin install git://github.com/look/xss_terminate.git

Follow Cost reviewed

Posted by Luke Francl
on Wednesday, December 03

Iyaz Akhtar of ChannelFlip Web (“The UK’s finest video magazine for switched on men”) has created a nice video reviewing Follow Cost!

Check it out:

In related news, our friend Joe Fiorini name-dropped Follow Cost in his 10 minute screencast about Sinatra. You can watch it here. Thanks Joe!

"Testing is Overrated" noted as one of 5 great talks

Posted by Luke Francl
on Monday, December 01

At Voices that Matter, I was really honored when Matt Knox named my Testing is Overrated talk as one of the 5 great Ruby talks of the last year, alongside names like DHH and Avi Bryant.

It’s true that the title is a little off-putting, but I think the core message is sound: as programmers, we spend too much time thinking about programmatic testing and not enough thinking about other ways to ensure code quality.

(Maybe if I’d called it Test All the Fucking Ways I’d have started a meme, too…)

If you missed the talk, InfoQ should be putting the video up on their website sometime before the heat death of the universe.

In the meanwhile, you can check out the slides….


and read the extensive handout I made….


Would you like me to give a version of this talk to your conference? I would love to do it again! Contact me.

Running in Packs vs. Going it Alone

Posted by Jon
on Wednesday, November 19

Most companies see competition as a threat. If someone’s products could substitute for mine, they’re a competitor; and if a potential customer chooses another product instead of mine, that’s a bad thing.

Lightweight startups take this even further. If you see a need, but another startup has already started addressing the need, then you came at it too late. You’re lightweight, and so your only real advantage is speed. But someone beat you to market. Makes sense, right?

Except it doesn’t work that way.

Going it alone

The typical, but wrong, paradigm goes like this:

  • Competition is bad
  • Competitors are enemies
  • Fewer competitors are better than more competitors
  • An opportunity addressed by a few people already is “taken”
  • An opportunity with zero competitors looks attractive

There is some truth to these things. Growing in the web search market today is pretty difficult. So is the operating system industry. So are dozens of other industries, and in these spaces, competitors may be be enemies.

But these are mature, settled industries. If you want to create a new search engine, or a new operating system, more power to you – but Google and Microsoft ARE going to be threats. Of course, most startups don’t try to dislodge Microsoft. If you’re working in an emerging market, on a disruptive or innovative technology, you might want to consider a different approach to competition.

Running in packs

This alternative model was described by Andrew Van de Ven of the University of Minnesota in an article called Running in Packs Versus Going It Alone. Andrew and his team found that in emerging, information-based technologies, competition often does not occur between individual startups, but between groups of startups. So as an alternative to trying to go it alone, startups may be better off running in packs: coordinating their efforts by simultaneously cooperating and competing.

This means that when a disruptive technology appears on the scene, its success is dependent upon the whole field of companies working on the technology, not on a single company.

So startups who run in packs should seek the growth of the entire market, in addition to trying to grow their own market share. Better to have a good slice of a growing market, than total domination of a dead market.

Actors seek both to maximize their total surplus and their respective shares in the surplus. ... This draws actors together and drives them to cooperate because no one actor has sufficient resources, competence, or legitimacy to do it alone.

Running in packs works for at least two reasons. First, competitors may help speed adoption of the emerging technology. Second, strong competition may improve and sharpen the quality of the technology.

This also means that politics is important when running in packs, as startups both compete and coordinate.

Actors with political savvy – an ability to recognize the interests of key actors and enroll them to one’s viewpoint – will be more successful in effecting institutional change and realizing their goals than actors without political savvy.

Van de Ven also found that the (disputed) first-mover advantage only really materializes with technologies with strong IP protection, and which can’t easily be reverse engineered, imitated, or substituted. Most web startups these days fall squarely in the “easily imitated” category – including giants like Facebook, Digg, Flickr, and Twitter. And even with a head start and strong patents, first movers may be better off seeking a pack to run with rather than going alone.

Of course, the advantage of running in packs probably only works up to a point. Settled, mature, and (worse) shrinking industries are far more competitive than emerging industries. This means that they’ll have a harder time working together to grow the whole industry, that adoption is less of a problem, and that technological improvement is slower.

This perhaps is why population ecology studies have found that having more competitors in a new organizational niche increases the survival probability of its members until a threshold level is reached where resource scarcity limits the growth of all members of a population.

A retail example

For a low-tech example of running in packs, look at clothing retailers. If going it alone worked in the retail industry, stores wouldn’t pay huge sums for space at the Mall of America – they would avoid it like the plague. After all, clothing stores are highly competitive – one can be substituted for another quite easily, and innovation happens slowly, with the basics (pants, shirts, socks) having been around for quite some time. So you would think that these stores would want to destroy their nearby competitors and be the only place to buy clothes for miles.

But in reality, the opposite is true. Retailers like to locate near other retailers, because going it alone as a retailer apparently doesn’t work very well. When someone needs a new pair of pants, their first thought is to go to a place where lots of people are selling pants. A shopping mall acts as a center of gravity to pull in buyers, and a lone clothing store without competition gets forgotten. So the stores simultaneously coordinate (bringing in lots of buyers to a single area) and compete with each other (for individual buyers). And as a pack, they compete with other packs of stores.

Consulting and Rails

Running in packs works for some location-based businesses, and it often works in emerging industries (the internet, mobile devices, etc.). But it also works with non-commercial technologies, like programming languages.

I’m a co-founder of Slantwise Design, a Ruby on Rails consulting shop. We mostly build web applications for startups. And while there are lots of companies trying to build web applications for startups, a majority of the time, our clients didn’t solicit bids from other competing shops. And as far as I’m aware, after 30+ projects and twice as many proposals, we’ve only competed directly with other Ruby on Rails shops twice.

(There are a few reasons for this, and I won’t go into them in much detail. The most important one is that by the time we give a proposal to a client, they’ve already made up their minds. They don’t want to decide between 10 consulting firms; they’re trying to confirm that we’ll do a good job.)

Ruby on Rails is still a growing technology, and adoption is still increasing. If you want to provide Rails consulting services, there is far more room to grow by taking business from Java or PHP shops than by taking business from other Rails shops. And the technology is still improving, so the growth of the Rails industry is fueled by knowledge sharing between Rails shops. Hence, not only is competition rare between Rails shops, but competitors should be seen as friends, not enemies.

So running in packs works for both Rails consulting firms, and for the proliferation of the Ruby on Rails technology itself.

What about you?

Every startup is different. But a lot of us need to start running in packs. Which model is best for your startup: running in packs or going it alone?

  Run in packs Go it alone
Market size Lots of growth potential Level or shrinking
Degree of innovation High – you spend time educating your customers Low – everyone already understands
IP protection Low – your startup could be imitated or substituted High – given time and money, someone could do what you’re doing
Industry concentration There is room for lots of companies to profit The industry will only support 1-2 companies


And of course, this leads into a second question: which sort of industry would you like to be a part of?


Further reading

This post is based on “Running in packs to develop knowledge-intensive technologies,” by Andrew Van de Ven. MIS Quarterly, June 1, 2005. You can buy this article at Amazon as a downloadable PDF for $3.95

For other thoughts on startups in emerging markets, check out Steve Blank’s Four Steps to the Epiphany.

iPhone as conference computer

Posted by Luke Francl
on Tuesday, November 18

I recently joined the cool kids and got an iPhone. As mentioned Jon and I are going to Voices that Matter: Professional Ruby Conference (or as I like to call it, Ruby that Matters) as guests of Pearson Education. Except at this conference, I am not going to bring my computer, just my iPhone.

Ruby that Matters

I think computers actually take away from the conference experience. They are heavy and distracting and you gotta baby sit the stupid thing all the time. The two redeeming qualities are that you can kill time if a session is boring, and you can hack code. Well, if the session is boring, instead of reading blogs, I’m going to leave. And if I want to hack, I’ll do some pair programming.

I’ll be taking notes in my trusty Moleskin as well as tweeting interesting bits using my iPhone. If you want to keep up with that, follow @lof on Twitter.

Update: So how’d it go?

I liked not having to lug around my computer—this is the lightest I’ve ever packed for a conference. Getting through airport security was a breeze.

I was able to tweet sporadic observations and I picked up a few new followers (hi!). I was also able to keep up on my email which was nice because I had some work stuff that needed attention.

There were two problems:

  1. MobileSafari crashes constantly. It drives me nuts.
  2. The iPhone 3G’s battery life is not long enough to stand all-day internet usage.

Aristotle and Software at RubyConf '08

Posted by Jon
on Friday, November 07

Here are slides from my talk earlier today entitled “Aristotle and the Art of Software Development”. I’m not sure how helpful the slides will be without the narration, but fortunately Confreaks recorded the conference. I’ll post a video (or link) here whenever it becomes available.

View SlideShare presentation or Upload your own. (tags: aristotle ruby)

Receiving Email with Ruby (and Rails)

Posted by Luke Francl
on Wednesday, November 05

Mailbox photo by a4gpaEarlier this year, Mike Mondragon and I co-authored a PeepCode book about MMS2R. But it was never really about MMS2R, it was about the broader topic of receiving and processing email with Ruby and Rails—and MMS2R is a key library for this. MMS2R makes processing multipart emails a snap. It does all the heavy lifting for you. The rest of the book explains the ins and outs of processing email with Rails, including best practices for matching users to the emails they submit.

Because of that, the book’s been renamed. It’s now called Receiving Email with Ruby.

Everyone I’ve talked to about the book has said that it’s been very helpful for them. If you’re looking at integrating email into your application, this is the place to start. Learn from Mike and my mistakes to your benefit! At only $9, it is a steal. Buy your copy today! :)

Photo by a4gpa.

Upgrading Phusion Passenger when Apache is installed from source

Posted by Luke Francl
on Thursday, October 30

I have a confession to make.

I hate the way Debian-based distributions handle Apache. sites-available, sites-enabled, esoteric commands to enable and disable sites, config files moved around from their usual places. Ugh. I just don’t like it. So I usually install Apace from source.

Here’s what you need to do to upgrade Phusion Passenger on Debian/Ubuntu when you’ve installed Apache from source.

When you run passenger-install-apache2-module, it will try to find Apache, and fail.

You need to set the following environment variables:

export APXS2=/usr/local/apache2/bin/apxs
export APR_CONFIG=/usr/local/apache2/bin/apr-1-config

With these set, the installer can find Apache and everything will work appropriately. Hopefully this information will help somebody out.

Via the Passenger documentation and Google Group.

Why you're drawn to mobile development

Posted by Jon
on Thursday, October 23

Mobile Orchard, a new blog covering iPhone and Android development, posted a great interview with Hampton Catlin this week to kick off the Mobile Orchard Podcast series.

Hampton Catlin of Unspace is probably best known in the Rails community for HAML, Sass, and Make Resourceful. He recently launched his first iPhone app, iWik iPedia. iPedia is a $0.99 Wikipedia browser that has sold over 50,000 copies so far. In this interview, Hampton talks about building the app, the process of working with Apple and the App Store, and more. If you’ve thought about building an iPhone app, this interview is definitely worth your time.

Mobile Orchard was created by Dan Grigsby and Peter Cooper. Peter is best known for Ruby Inside and a book on Ruby. Dan Grigsby is a Rail Spikes blogger emeritus, entrepreneur, and Ruby/Haskell/iPhone hacker. So far, the content is a good mix of iPhone news and original content (like the podcast, and a video walkthrough of an early Android phone). Knowing Dan and Peter, this blog should be worth a spot in any aspiring mobile developer’s feed reader.

Why mobile development?

I don’t know about you, but I’m feeling the draw of mobile development. Luke is too. So are Hampton, Dan, and lots of other folks in (and out of) the Ruby community.

Why is this? After all, mobile app development is a lot more like building desktop apps than like building web apps. Take the iPhone: desktop Cocoa programmers have a huge head start over us web programmers. You have to use low-level languages like Objective-C. You’re locked into a closed and developer-ambivalent (sometimes developer-unfriendly) platform.

So why move from the web to the iPhone? There are good reasons.

1. It’s different.

Building an iPhone app is very different than building a Rails web app. For some developers, this is a problem. We call those people bad developers. Good developers build software, not Ruby/Java/Lisp/Blubb code. In other words, they’re not interested in mastering a single tool and staying there as long as they can. They may specialize, certainly – become a really really good Ruby/Java/Lisp/Blub developer – but don’t stop there. The Pragmatic Programmer famously recommends learning a new language every year, and this is great advice.

So why the iPhone? Because there is something to be said for learning languages and tools at opposite ends of the spectrum. Should a Ruby developer learn Python, a reasonably close cousin? Maybe, in order to learn the quirks of Ruby and to find other approaches to similar problems. But should a developer learn Ruby, Python, Perl, Lua, and PHP? Probably not, because these languages are largely redundant, and there is more to software than just dynamic high-level languages.

Learning Cocoa and Objective-C doesn’t just teach new approaches to the same problems – it teaches new approaches to new problems.

2. It’s a framework.

Web application developers these days are used to using frameworks. So while Cocoa and Rails have little in common, the approach of using a framework like Cocoa is comfortable to web app developers. Unlike, perhaps, moving from Rails to raw C++ or raw Haskell.

3. Money!

Success stories like Hampton’s always catch the eye of a certain class of developers. These developers used to run micro-ISVs. (Remember that term?) Nowadays, they often gravitate to Ruby or Python or PHP. They aren’t looking for a stable career at a big organization, and they aren’t looking for VC funding or an IPO. They just want to build cool things and make some money from it.

The iPhone App Store caters to this type of developer. Setting aside for a minute Apple’s benevolent (or s/ben/mal?) dictatorship over the App Store, the whole focus is on helping people monetize their applications. The entrepreneurial developer’s dream is to:

  • build something cool
  • in a reasonably short amount of time
  • and make money from it on an ongoing basis with minimal marketing and maintenance.

That’s what the App Store is all about.

4. Ride the growth trends.

The web was a huge growth trend in the late 1990’s, and again over the past few years, in new-and-improved “2.0” form. Whenever possible, it’s smart to ride this momentum.

Is “mobile” a growth trend today? It looks like it, and a lot of people are betting that it is. But more on that in a minute.

5. Diversify.

If you’ve focused on Rails development for the last few years, you might be feeling the need to expand your portfolio. There is still a lot of Rails work out there, and are still a lot of interesting web apps to build. But most of us won’t be doing the same thing in 5 years than we’re doing today, and learning another marketable skill is always helpful. Which would you rather have on your resume?

  • Rails developer since 2005

Or

  • Rails developer since 2005
  • Ajax developer since 2006
  • Merb developer since 2007
  • iPhone developer since 2008
  • Next Big Thing developer since 2009

I’ll take the latter.

Trend or bubble?

The App Store has been a worthwhile platform for Hampton and lots of other developers. My question is this: will that continue? Are App Store sales on the decline, now that the novelty has worn off; or will they increase over time? Think of Facebook Apps: for about 3 months, even the stupidest Facebook App was made of gold. (Especially the stupidest?) But now there are tens of thousands of Facebook apps that haven’t gone anywhere, and the growth stage is over. For now, at least.

The traditional growth model for successful ventures looks like this. The App Store skipped the early stage (slow growth, waiting for traction) and jumped right to the vertical bit of the hockey stick. But rapid growth can’t continue forever, and eventually even IBM and Microsoft are no longer growth companies. That’s the top part of the idealized growth model.

So where are iPhone apps? Do they have years of growth in front of them, or is the boom over?

Ruby conferences that matter

Posted by Jon
on Tuesday, October 14

As Ruby on Rails grows, matures, and gains mainstream acceptances, so proliferate the conferences. RailsConf US, RailsConf Europe, and RubyConf. EuRoKo, RubyKaigi, Scotland, Latin America, Canada, Nederlands. Rails Edge. Half a dozen regional conferences. The Ruby conference’s bad-influence punk cousin, RubyFringe. And now Voices That Matter: Professional Ruby Conference, the worst-named conference since NeoCon® Xpress L.A. But Obie Fernandez, the conference chair, has already addressed the name issue (“Voices that matter? SRSLY? Does that mean people not speaking at the conference don’t matter?”), so there isn’t much more to say about that.

Luke, Eric, and I will be attending the conference next month (November 17-20), thanks to generous complementary passes. We’re suckers for free conferences and are looking forward to it. They’ve also offered a $200 discount to our readers, so if you decide to attend, use this discount code and save: PR2MAL4.

Here is my take on the conference.

1. Boston: great city. Should be fun.

2. Obie was inspired by RubyFringe. Single track, 30 minute talks, 150 attendees (?).

3. The agenda looks pretty professional and, well, straight. For better or for worse. Four case studies, several few enterprise-focused talks, and every base covered: scaling, refactoring, testing, plugins, deployment, etc. Fortunately, Giles Bowkett will also be there with a talk entitled “Beyond the Mountains of Madness with Ruby.” As with any conference, expect some flops and some good talks, and hope for some great talks.

4. The speaker list looks pretty good, including two of our very own Twin Cities folks: Matt Bauer and Tom Enebo.

5. Timing: why is this held two weeks after RubyConf? I’ll be at both, and missing work for two conferences in a month isn’t quite ideal.

6. Some sort of vocal performance seems to be involved. (Obie, is that you?)

If you’re interested in going, you can get $200 off the entry price by using this discount code: PR2MAL4.

follow cost: what a day!

Posted by Luke Francl
on Monday, October 13

Whew. It’s been a crazy day.

Barry and I launched follow cost this morning with a blog post here and at his blog—and of course, we tweeted it.

Despite some problems (which we later figured out was our site getting rate limited by Twitter) the site really took off.

We had requests to sponsor the site within minutes.

By 2 PM we were on valleywag (though without a link. Thanks guys!)

This evening, Scoble tweeted about the site which lead to a blizzard of requests. I’ve got to say he has a great sense of humor about the whole milliscoble thing!

And now, we’ve signed up our first sponsor: Peter Cooper and Dan Grigsby’s (friend of the site) new mobile development blog Mobile Orchard.

Whew. Making something that goes viral is fun, but it’s a lot of work!

Announcing follow cost: Is that Twitter celebrity worth the pain?

Posted by Luke Francl
on Monday, October 13

Have you ever wondered if it was worth following someone on Twitter?

Now you have another tool to help you make that decision: follow cost. Give follow cost a Twitter user name and it will calculate how often they tweet on average. As a yard stick, follow cost uses the milliscoble, defined as 1/1000th of the average daily Twitter output of Robert Scoble. As an example, here’s my follow cost (currently, 133 milliscobles).

There’s even a bookmarklet you can use when viewing a Twitter profile.

We’ve got some neat features planned for the future, but to do them, we need better hosting. So we’re looking for a sponsor. Contact me if you’re interested.

Building follow cost

I built follow cost with my friend (and Harvest developer) Barry Hess. The idea for a service “to tell you how annoying someone would be to follow on Twitter” was hatched on our road trip to Windy City Rails a few weeks ago. (Fourteen hours in a van with 6 programmers is a long, long time.)

Barry and I decided that we wanted to do something a little different than the traditional Rails project.

We chose to use Sinatra. Sinatra was perfect for this project. It has very few dependencies. The routing is explicit and an integral part of your app. The app itself has only a few pages and doesn’t use a database. Really, anything else would be overkill.

We also decided to use jQuery for JavaScript, since neither of us had tried it before. It worked well, I can see why people like it.

To actually power the application, we call the Twitter API (using REXML) and the Twitter Search API (using JSON).

To keep things snappy, we implemented a page caching system for Sinatra that works very similarly to Twistr’s, which I described earlier.

Deployment was handled with Passenger and Rack based on these instructions.

Introduction to Merb

Posted by Luke Francl
on Thursday, October 09

One of the most enduringly popular articles on Rail Spikes is my introduction to Merb from back in April, 2007(!): Merb (and why you potentially should care).

pageviews graph for Merb article

Obviously Merb has changed a lot since that article was written, so it is completely out of date (I think it was about Merb 0.4 or something like that).

Fortunately, Matt Todd (who I met at RubyFringe—look for his talk on InfoQ one of these months) has a much better look at where the Merb framework is today, as it approaches its 1.0 release at MerbCamp this weekend. Matt presented this at AltRUG yesterday.

Check it out. (Also, you may be interested in Jon’s interview with Ezra Zygmuntowicz from back in June.)

Finding CSS problems with binary search

Posted by Luke Francl
on Friday, October 03

I’m trying to integrate the YUI Rich Text Editor in to an application which has some CSS rules that aren’t playing nice.

But how to find what’s causing the problem in a 1700 line CSS file?

Binary search to the rescue!

Binary search (see also this introduction from Princeton) is a divide-and-conquer algorithm for finding an item in a sorted list. On each iteration, it cuts the total search space in half.

Binary search diagram

It can also be used as a heuristic tool for finding software defects. The bisect command in git and Mercurial allows you to do a binary search through your code to find the revision where a bug was introduced.

Lately, I’ve been using it to find CSS problems.

Here’s what I do. I select half the file (roughly—obviously, you need to break it after a CSS expression), and delete it. Then I reload the page.

  • Problem still there? I know the problem is in the half I didn’t delete.
  • Problem fixed? I know the problem is in the half that I just deleted.

Restore the file, and delete the next subdivision. Within just a few iterations, you should be on a specific CSS rule that’s causing problems.

Anyway, maybe it’s old hat to most people, but I thought it was kind of cool.

Publishing non-ActiveRecord objects in an Atom feed with Rails

Posted by Luke Francl
on Wednesday, October 01

Rails comes with a method called atom_feed that makes it really easy to publish an Atom feed for a list of ActiveRecord objects.

Here’s an example from the documentation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
atom_feed do |feed|
  feed.title("My great blog!")
    feed.updated((@posts.first.created_at))

    for post in @posts
      feed.entry(post) do |entry|
        entry.title(post.title)
        entry.content(post.body, :type => 'html')

        entry.author do |author|
          author.name("DHH")
        end
      end
    end
  end
end

For each <entry>, the Atom elements for <id>, <published>, <updated>, and <link> are automatically assigned based on the methods id, created_at, updated_at and polymorphic_url respectively.

However, I wanted to publish a non-ActiveRecord object in the feeds for Tumblon. Specifically, a group of photos.

multi-photo post example

Each of these elements can be specified directly, except <id>. So you could do something like this:

1
2
3
4
5
6
7
8
feed.entry(post, :url => my_custom_url, :published => post.some_date, :updated => post.some_other_date) do |entry|
  entry.title(post.title)
  entry.content(post.body, :type => 'html')

  entry.author do |author|
    author.name("DHH")
  end
end

The big problem with this is if you’re using a non-ActiveRecord object, it won’t have a stable id, and so the Atom feed’s <id> will change every time the feed is generated—leading to duplicate posts in feed readers. So you need to conjure up a stable id for your non-ActiveRecord object.

In my case, I created an stable id using my list of photos. I also added created_at and updated_at methods so I don’t have to specify them when creating the feed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MultiPhotoPost
  # truncated ...
  
  # override id so that the atom feed <id> doesn't change between runs
  def id
    created_at.to_i
  end
  
  def created_at
    @created_at ||= photos.min { |a, b| a.created_at <=> b.created_at }.created_at
  end
  
  def updated_at
    @updated_at ||= photos.max { |a, b| a.updated_at <=> b.updated_at }.updated_at
  end

end

With this in place, you’ll just need to specify the URL for the object (since polymorphic_url won’t work) when you create the feed <entry>.